package org.zfes.snowier.cloud.zbss.pmp.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.zfes.snowier.core.data.ComboboVo;
import org.zfes.snowier.core.data.DataSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;

import org.zfes.snowier.core.util.ZDateUtil;
import org.zfes.snowier.core.util.ZObjectUtil;

import com.google.common.collect.Lists;

import org.zfes.snowier.core.util.ZAlert;
import org.zfes.snowier.core.util.ZAssert;
import org.zfes.snowier.common.dao.params.ParamMap;
import org.zfes.snowier.cloud.zbss.pmp.service.IPmpCloudMemberService;
import org.zfes.snowier.cloud.zbss.pmp.service.IPmpProjectService;
import org.zfes.snowier.cloud.zbss.pmp.service.IpmpProjectGroupService;
import org.zfes.snowier.cloud.zbss.pmp.dao.pmpProjectGroupMapper;
import org.zfes.snowier.cloud.zbss.pmp.dto.PmpProjectGroupDetailDto;
import org.zfes.snowier.cloud.zbss.pmp.model.PmpCloudMember;
import org.zfes.snowier.cloud.zbss.pmp.model.PmpProject;
import org.zfes.snowier.cloud.zbss.pmp.model.PmpProjectGroup;

import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class PmpProjectGroupServiceImpl implements IpmpProjectGroupService {
	@Autowired
	private pmpProjectGroupMapper pmpProjectGroupMapper;
	@Autowired
	private IPmpProjectService pmpProjectService;
	@Autowired
	private IPmpCloudMemberService pmpCloudMemberService;

	@Transactional(rollbackFor = Exception.class, readOnly = true)
	@Override
	public Optional<PmpProjectGroup> loadpmpProjectGroupById(Long id) {
		if (id != null) {
			return Optional.ofNullable(pmpProjectGroupMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();

	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void setpmpProjectGroupStatus(Long id, Byte status) {
		ZAssert.notNull(id, "请选择要操作的数据");
		ZAssert.notNull(status, "状态参数错误");// #1正常，-1移除 #
		if (!Stream.of(new Byte[] { -1, 1 }).anyMatch(val -> val.equals(status))) {
			ZAlert.serviceLogicalError("状态参数错误");
		}
		pmpProjectGroupMapper.updateStatus(id, status);
	}

	@Transactional(rollbackFor = Exception.class, readOnly = true)
	@Override
	public DataSet loadpmpProjectGroupDataSet(Map<String, Object> params) {
		ParamMap pm = ParamMap.filterParam(params);
		DataSet ds = DataSet.newDS2(pmpProjectGroupMapper.selectListCount(pm),pmpProjectGroupMapper.selectMapListPage(pm));
		return ds;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void deleteOnePmpProjectGroupMember(Long projectId,Long userId,Byte userType) {
		
		PmpProjectGroup projectGroup=	pmpProjectGroupMapper.selectByProIdAndUIdAndUType(projectId, userId, userType);
		ZAssert.notNull(projectGroup, "未查询到数据");
		
		this.setpmpProjectGroupStatus(projectGroup.getId(),Byte.valueOf("-1"));
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void addOnePmpProjectGroupMember(Long projectId, Long userId, Byte userType) {
		ZAssert.notNull(projectId, "请选择要操作的数据");
		ZAssert.notNull(userId, "请选择要操作的数据");

		PmpCloudMember member = pmpCloudMemberService.loadPmpCloudMemberById(userId).orElseThrow(() -> ZAlert.newSLE("该成员不存在"));
		PmpProjectGroup projectGroup = pmpProjectGroupMapper.selectByProIdAndUIdAndUType(projectId, userId,userType);
		if (projectGroup != null) {// #1正常，-1移除 #
			pmpProjectGroupMapper.updateStatus(projectGroup.getId(), Byte.valueOf("1"));
		} else {
			if (userType.equals(Byte.valueOf("3"))) {// 检验项目经理是否已添加
				
				List<PmpProjectGroup> groupList=pmpProjectGroupMapper.selectByProIdAndUType(projectId, userType);
				if(ZObjectUtil.isNotEmpty(groupList)&&groupList.size()>1) {
					ZAlert.serviceLogicalError("项目经理已存在，请不要重复添加");
				}
			}
			PmpProjectGroup projectGroupNew = new PmpProjectGroup();
			projectGroupNew.setProjectId(projectId);
			projectGroupNew.setUserId(userId);
			projectGroupNew.setUserType(userType);
			projectGroupNew.setUserName(member.getUserName());
			projectGroupNew.setCreatetime(ZDateUtil.newDate());
			projectGroupNew.setUpdatetime(ZDateUtil.newDate());
			pmpProjectGroupMapper.insertSelective(projectGroupNew);
		}
		pmpProjectService.updatePmpProjectMemberCount(projectId, Integer.valueOf("1"));

	}

	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<PmpProjectGroupDetailDto> loadProjectGroupMembers(Long projectId) {
		if(ZObjectUtil.isNull(projectId)) {
			return Optional.empty();
		}
		Optional<PmpProject> pmpProjectOp=pmpProjectService.loadPmpProjectById(projectId);
		if(!pmpProjectOp.isPresent()) {
			return Optional.empty();
		}
		PmpProjectGroupDetailDto detail=new PmpProjectGroupDetailDto(pmpProjectOp.get());
		
		//成员类型_D#1开发，2测试，3项目经理，4管理员#
		List<PmpProjectGroup> projectGroups= loadPmpProjectGroupByProjectId(projectId);
		
		List<PmpCloudMember> pmpCloudMembers = pmpCloudMemberService.loadPmpCloudMemberByIds(projectGroups.stream().map(val->val.getUserId()).collect(Collectors.toList()));
		if(ZObjectUtil.isEmpty(pmpCloudMembers)) {
			return Optional.of(detail);
		}
		
		Long gma=projectGroups.stream().filter(val->val.getUserType().equals(Byte.valueOf("3"))).findFirst().map(val->val.getUserId()).get();
		
		Set<Long> gdevList =  projectGroups.stream().filter(val->val.getUserType().equals(Byte.valueOf("1"))).map(val->val.getUserId()).collect(Collectors.toSet());
		
		Set<Long> gtestList =  projectGroups.stream().filter(val->val.getUserType().equals(Byte.valueOf("2"))).map(val->val.getUserId()).collect(Collectors.toSet());
		
		
		PmpCloudMember pmUser=pmpCloudMembers.stream().filter(val->val.getId().equals(gma)).findFirst().get();
		
		List<PmpCloudMember> devList = pmpCloudMembers.stream().filter(val->gdevList.contains(val.getId())).collect(Collectors.toList());
		List<PmpCloudMember> testList = pmpCloudMembers.stream().filter(val->gtestList.contains(val.getId())).collect(Collectors.toList());
		
		detail.setDevUserList(devList).setTestUserList(testList).setPmUser(pmUser);
		return Optional.of(detail);
		
		
	}
	@Transactional(rollbackFor = Exception.class, readOnly = true)
	@Override
	public List<ComboboVo> loadProjectGroupComboboVo(Long projectId) {
		Optional<PmpProjectGroupDetailDto> groupDto= loadProjectGroupMembers( projectId);
		if(!groupDto.isPresent()) {
			return Lists.newArrayList();
		}
		List<ComboboVo> voList=Lists.newArrayList();
		voList.add(new ComboboVo(groupDto.get().getPmUser().getId(), "[项目经理]: "+groupDto.get().getPmUser().getUserName()));
		groupDto.get().getDevUserList().forEach(val->voList.add(new ComboboVo(val.getId(), "[开发]: "+val.getUserName())));
		groupDto.get().getTestUserList().forEach(val->voList.add(new ComboboVo(val.getId(), "[测试]: "+val.getUserName())));
		voList.add(0,new ComboboVo("", "请选择数据"));
		return voList;
	}

	

	@Transactional(rollbackFor = Exception.class, readOnly = true)
	@Override
	public List<PmpProjectGroup> loadPmpProjectGroupByUseId(Long userId) {
		PmpCloudMember member = pmpCloudMemberService.loadPmpCloudMemberById(userId).orElseThrow(() -> ZAlert.newSLE("该成员不存在"));
		ZAssert.equals(member.getStatus(), Byte.valueOf("1"), "该成员当前状态错误");

		List<PmpProjectGroup> pmpProjectGroupList = pmpProjectGroupMapper.selectByUseId(userId);
		return pmpProjectGroupList;
	}

	@Transactional(rollbackFor = Exception.class, readOnly = true)
	@Override
	public List<PmpProjectGroup> loadPmpProjectGroupByProjectId(Long projectId) {

		ZAssert.notNull(projectId, "请选择要操作的数据");
		pmpProjectService.loadPmpProjectById(projectId).orElseThrow(() -> ZAlert.newSLE("未找到该项目数据"));

		List<PmpProjectGroup> arrayList = Lists.newArrayList();

		arrayList = pmpProjectGroupMapper.selectByProjectId(projectId, Byte.valueOf("1"));
		return arrayList;
	}


}